import { Injectable, ConflictException, NotFoundException } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { User, UserDocument } from './schemas/user.schema';
import { CreateUserDto } from './dto/create-user.dto';
import * as bcrypt from 'bcrypt';
import { UpdateUserDto } from './dto/update-user.dto';

// 返回类型定义
interface UserWithPermissions {
  permissions: string[];
  [key: string]: any;
}

@Injectable()
export class UsersService {
  constructor(
    @InjectModel(User.name) private userModel: Model<UserDocument>,
  ) {}

  async create(createUserDto: CreateUserDto): Promise<User> {
    // 先检查用户名是否已存在
    const existingUser = await this.userModel.findOne({ 
      username: createUserDto.username 
    }).exec();
    
    if (existingUser) {
      throw new ConflictException('用户名已被占用');
    }
    
    const createdUser = new this.userModel(createUserDto);
    return createdUser.save();
  }

  async findAll(): Promise<User[]> {
    return this.userModel.find().exec();
  }

  async findOne(id: string): Promise<User | null> {
    return this.userModel.findById(id).exec();
  }

  async findByUsername(username: string): Promise<User | null> {
    return this.userModel.findOne({ username }).exec();
  }

  async findOneWithPermissions(userId: string): Promise<UserWithPermissions | null> {
    // 查找用户并关联其角色和权限
    const user = await this.userModel.findById(userId)
      .populate({
        path: 'roleIds',
        populate: {
          path: 'permissionIds',
          model: 'Permission'
        }
      })
      .exec();
      
    if (!user) {
      return null;
    }
    
    // 提取所有权限代码
    const permissions: string[] = [];
    
    // 从用户的角色中提取权限
    if (user.roleIds && user.roleIds.length > 0) {
      for (const role of user.roleIds as any[]) {
        if (role.permissionIds && role.permissionIds.length > 0) {
          for (const permission of role.permissionIds as any[]) {
            if (permission.code) {
              permissions.push(permission.code);
            }
          }
        }
      }
    }
    
    // 返回带有权限的用户对象
    return {
      ...user.toObject(),
      permissions
    };
  }

  async updateLastLoginTime(userId: string): Promise<void> {
    await this.userModel.findByIdAndUpdate(userId, {
      lastLoginTime: new Date()
    }).exec();
  }

  // 查找使用特定角色的用户
  async findUsersByRoleId(roleId: string): Promise<User[]> {
    return this.userModel.find({ roleIds: roleId }).exec();
  }

  // 从用户的角色列表中移除指定角色
  async removeRoleFromUsers(roleId: string): Promise<void> {
    await this.userModel.updateMany(
      { roleIds: roleId },
      { $pull: { roleIds: roleId } }
    ).exec();
  }

  // 检查机构下是否有用户
  async hasUsersByOrgId(orgId: string): Promise<boolean> {
    const count = await this.userModel.countDocuments({ orgId }).exec();
    return count > 0;
  }

  // 获取机构下的所有用户
  async findUsersByOrgId(orgId: string): Promise<User[]> {
    return this.userModel.find({ orgId }).exec();
  }

  async update(id: string, updateUserDto: UpdateUserDto): Promise<User> {
    if (updateUserDto.password) {
      const salt = await bcrypt.genSalt();
      updateUserDto.password = await bcrypt.hash(updateUserDto.password, salt);
    }
    
    const updatedUser = await this.userModel.findByIdAndUpdate(
      id, 
      updateUserDto, 
      { new: true }
    ).exec();
    
    if (!updatedUser) {
      throw new NotFoundException(`用户ID ${id} 不存在`);
    }
    
    return updatedUser;
  }

  async remove(id: string): Promise<void> {
    const result = await this.userModel.findByIdAndDelete(id).exec();
    
    if (!result) {
      throw new NotFoundException(`用户ID ${id} 不存在`);
    }
  }

  async removeMany(ids: string[]): Promise<void> {
    await this.userModel.deleteMany({ _id: { $in: ids } }).exec();
  }
} 